package com.tlgen.orm.utils.reflect;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class InterfaceScannerUtils {

    // 缓存接口到其实现类的映射
    private static final Map<String, List<String>> INTERFACE_TO_IMPL_CACHE = new ConcurrentHashMap<>();

    // 缓存项目源码根路径
    private static volatile Path SOURCE_ROOT_PATH;

    // 实现类后缀
    private static final String IMPL_SUFFIX = "Impl";

    /**
     * 获取指定接口的实现类（高性能缓存版）
     */
    public static List<String> getImplClassesByInterfaceClassName(String interfaceClassName) {
        // 检查缓存
        if (INTERFACE_TO_IMPL_CACHE.containsKey(interfaceClassName)) {
            return INTERFACE_TO_IMPL_CACHE.get(interfaceClassName);
        }

        // 确保源码根路径已初始化
        ensureSourceRootPath();

        if (SOURCE_ROOT_PATH == null) {
            return Collections.emptyList();
        }

        // 获取接口简单名称
        String interfaceSimpleName = getSimpleClassName(interfaceClassName);

        // 查找实现类
        List<String> implClassNames = findImplClasses(interfaceClassName, interfaceSimpleName);

        // 缓存结果 - 接口类名映射到实现类列表
        INTERFACE_TO_IMPL_CACHE.put(interfaceClassName, implClassNames);

        return implClassNames;
    }

    /**
     * 确保源码根路径已初始化
     */
    private static synchronized void ensureSourceRootPath() {
        if (SOURCE_ROOT_PATH == null) {
            SOURCE_ROOT_PATH = detectSourceRootPath();
        }
    }

    /**
     * 检测源码根路径
     */
    private static Path detectSourceRootPath() {
        try {
            // 尝试从类加载器获取资源
            URL resource = InterfaceScannerUtils.class.getClassLoader().getResource("");
            if (resource != null) {
                Path classPath = Paths.get(resource.toURI());

                // 尝试推导源码路径
                if (classPath.toString().contains("target/classes")) {
                    return classPath.resolveSibling("src/main/java");
                }
            }

            // 尝试常见路径
            Path candidate = Paths.get(System.getProperty("user.dir"), "src", "main", "java");
            if (Files.isDirectory(candidate)) {
                return candidate;
            }

            // 最后尝试当前目录
            return Paths.get("");
        } catch (Exception e) {
            return Paths.get(System.getProperty("user.dir"));
        }
    }

    /**
     * 查找实现类
     */
    private static List<String> findImplClasses(String interfaceFullName, String interfaceSimpleName) {
        try {
            // 构建实现类文件名模式
            String implClassFileNamePattern = ".*" + Pattern.quote(interfaceSimpleName) + IMPL_SUFFIX + "\\.java";

            // 使用 NIO 文件遍历 API
            List<Path> implFiles = new ArrayList<>();
            Files.walkFileTree(SOURCE_ROOT_PATH, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    if (file.toString().endsWith(".java") &&
                            file.getFileName().toString().matches(implClassFileNamePattern)) {
                        implFiles.add(file);
                    }
                    return FileVisitResult.CONTINUE;
                }
            });

            // 构建实现接口的正则模式
            Pattern implementationPattern = Pattern.compile(
                    "\\bimplements\\s+" + Pattern.quote(interfaceSimpleName) + "\\b"
            );

            return implFiles.parallelStream()
                    .filter(file -> isImplementationClass(file, implementationPattern, interfaceFullName))
                    .map(InterfaceScannerUtils::convertPathToClassName)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
        } catch (IOException e) {
            return Collections.emptyList();
        }
    }

    /**
     * 检查文件是否为实现类
     */
    private static boolean isImplementationClass(Path file, Pattern implementationPattern, String interfaceFullName) {
        try {
            // 读取文件内容
            String fileContent = new String(Files.readAllBytes(file), "UTF-8");

            // 检查关键特征
            return fileContent.contains("implements " + interfaceFullName) ||
                    implementationPattern.matcher(fileContent).find();
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 将文件路径转换为类名
     */
    private static String convertPathToClassName(Path file) {
        try {
            // 计算相对于源码根路径的相对路径
            Path relativePath = SOURCE_ROOT_PATH.relativize(file);

            // 转换为类名格式
            return relativePath.toString()
                    .replace(".java", "")
                    .replace(File.separatorChar, '.');
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 从完整类名获取简单类名
     */
    private static String getSimpleClassName(String fullClassName) {
        int lastDot = fullClassName.lastIndexOf('.');
        return lastDot >= 0 ? fullClassName.substring(lastDot + 1) : fullClassName;
    }

    /**
     * 清除缓存
     */
    public static void clearCache() {
        INTERFACE_TO_IMPL_CACHE.clear();
    }

    /**
     * 调试方法：打印源码根路径
     */
    public static void printSourceRootPath() {
        System.out.println("Source root path: " +
                (SOURCE_ROOT_PATH != null ? SOURCE_ROOT_PATH.toAbsolutePath() : "null"));
    }

    /**
     * 手动设置源码路径（用于调试）
     */
    public static void setSourceRootPath(Path path) {
        SOURCE_ROOT_PATH = path;
        clearCache();
    }
    
}